#include <bits/stdc++.h>
using namespace std;

// #define ONLINE_JUDGE

#ifndef ONLINE_JUDGE
#define dbg(x...)                             \
	{                                         \
		cerr << "\033[32;1m" << #x << " -> "; \
		err(x);                               \
	}
void err()
{
	cerr << "\033[39;0m" << endl;
}
template <typename T, typename... A>
void err(T a, A... x)
{
	cerr << a << ' ';
	err(x...);
}
#else
#define dbg(...)
#endif

const int N = 18;

char mp[N + 5][N + 5]; 

struct RowState
{
	short cost;
	int fa;
} rec[N + 5][1 << N];

struct ColState
{
	short cost;
	char var;
} dp[N + 5][1 << N];

int n, m;

int main(int argc, char const *argv[])
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i)
		scanf("%s", mp[i]);
	int lim = 1 << m;

	for (int i = 0; i < n; ++i)
		memset(rec[i], -1, sizeof(RowState) * lim);
	rec[0][1] = RowState{0, -1};

	for (int i = 0; i < n; ++i)
	{
		// restore from last row
		for (int j = 0; j < lim; ++j)
		{
			dp[0][j] = ColState{rec[i][j].cost, -1};
		}

		for (int j = 0; j < m; ++j)
		{
			memset(dp[j + 1], -1, sizeof(ColState) * (lim));
			for (int u = 0; u < lim; ++u)
			{
				short nowCost = dp[j][u].cost;
				if (nowCost == -1)
					continue;
				// dbg(i, j, u);
				// try to put X here
				if (mp[i][j] != '.')
				{
					bool check = !(u & (1 << j)) || (j == m-1) ||  (j + 1 < m && (u & (1 << (j + 1)))); // . in last row is stopped
					if (check)
					{
						int v = u & ~(1 << j);
						if (nowCost > dp[j + 1][v].cost)
						{
							dp[j + 1][v] = ColState{nowCost, (u >> j) & 1};
						}
					}
				}

				// try to put . here
				if (mp[i][j] != 'X')
				{
					int check = ((u >> j) & 1) + (j > 0 ? ((u >> (j - 1)) & 1) : 0);
					// shouldn't have 2 path to get here
					if (check == 1)
					{
						int v = u | (1 << j);
						if (nowCost + 1 > dp[j + 1][v].cost)
						{
							dp[j + 1][v] = ColState{nowCost + 1, (u >> j) & 1};
						}
					}
				}
			}
		}

		for (int k = 0; k < lim; ++k)
		{
			int cur = k;
			short curCost = dp[m][cur].cost;
			if (curCost == -1)
				continue;
			for (int u = m - 1; u >= 0; --u)
			{
				int var = dp[u + 1][cur].var;
				cur = (cur & ~(1 << u)) | (var << u);
				// restore the u-th bit
			}
			rec[i + 1][k] = RowState{curCost, cur};
			// dbg(i, k, rec[i + 1][k].fa, rec[i+1][k].cost);
		}
	}

	// get from the last row
	RowState ans = {0, 0};
	// int u;
	for (int k = 0; k < lim; ++k)
	{
		if (ans.cost < rec[n][k].cost)
		{
			ans = RowState{rec[n][k].cost, k};
		}
	}
	if (ans.cost == 0)
	{
		puts("-1");
	}
	else
	{ 
		int u = ans.fa;
		for (int i = n - 1; i >= 0; --i)
		{
			// dbg(i, u);
			for (int j = 0; j < m; ++j)
			{
				mp[i][j] = (u & (1 << j) ? '.' : 'X');
			}
			u = rec[i + 1][u].fa;
		}
		printf("%d\n", ans.cost);
		for (int i = 0; i < n; ++i)
			printf("%s\n", mp[i]);
	}

	return 0;
}
